package trading.ctm.yunjing.view;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Point;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import trading.ctm.yunjing.R;


/**
 * 自定义简单曲线图
 * <p/>
 * Created by CQ
 */
public class LineGraphicView extends View {
    /**
     * 公共部分
     */
    private Context mContext;
    private Paint mPaint;
    private Paint mPaint2;
    private Resources res;
    private DisplayMetrics dm;
    private int canvasHeight;
    private int canvasWidth;
    private int bheight = 0;
    private int blwidh;
    private boolean isMeasure = true;

    private int startXWidth;
    /**
     * Y轴最大值
     */
    private int maxValue;
    /**
     * Y轴间距值
     */
    private int averageValue;
    private int marginTop = 20;
    private int marginBottom = 40;

    /**
     * 曲线上总点数
     */
    private Point[] mPoints;
    /**
     * 纵坐标值
     */
    private ArrayList<Double> yRawData;
    /**
     * 横坐标值
     */
    private ArrayList<String> xRawDatas;
    private ArrayList<Integer> xList = new ArrayList<>();// 记录每个x的值
    private int spacingHeight = 5;

    public LineGraphicView(Context context) {
        this(context, null);
    }

    public LineGraphicView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
        initView();
    }


    private int screenWidth;
    private int screenHeight;
    private long screenAll;


    private Paint mPaintCoveredBg;


    //阴影路径的画笔
    private Paint mPaint_path;

    private void initView() {
        this.res = mContext.getResources();
        this.mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        this.mPaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
        dm = new DisplayMetrics();
        WindowManager wm = (WindowManager) mContext
                .getSystemService(Context.WINDOW_SERVICE);
        Display defaultDisplay = wm.getDefaultDisplay();
        defaultDisplay.getMetrics(dm);
        screenWidth = defaultDisplay.getWidth();
        screenHeight = defaultDisplay.getHeight();
        screenAll = screenWidth * screenHeight;
        mPaintCoveredBg = new Paint();
        mPaintCoveredBg.setColor(Color.RED);
        mPaintCoveredBg.setStyle(Style.FILL);

        //注意path的画笔的透明度已经改变了
        mPaint_path = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint_path.setColor(Color.argb(0x33, 0x91, 0xC8, 0xD6));
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(dip2px(50) * xRawDatas.size(), heightMeasureSpec);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        if (isMeasure) {
            this.canvasHeight = getHeight();
            this.canvasWidth = getWidth();
            if (bheight == 0)
                bheight = canvasHeight - marginBottom - 100;
            blwidh = dip2px(50);
            startXWidth = dip2px(30);
            isMeasure = false;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        mPaint.setColor(res.getColor(R.color.color_1A693C26));
        mPaint2.setColor(res.getColor(R.color.color_FFFFFF));
        drawAllXLine(canvas);
        // 画直线（纵向）
        drawAllYLine(canvas);
        // 点的操作设置
        mPoints = getPoints();
        mPaint.setColor(res.getColor(R.color.color_693C26));
        mPaint.setStrokeWidth(dip2px(0.5f));


        mPaint.setStyle(Style.FILL);
        for (int i = 0; i < mPoints.length; i++) {
            canvas.drawCircle(mPoints[i].x - startXWidth, mPoints[i].y, 10, mPaint);
            mXAndMonth.put(yRawData.get(i) + "", new int[]{mPoints[i].x, mPoints[i].y});// 添加点的X坐标和对应的月份到map集合中
        }
        mPaint.setStyle(Style.STROKE);
        mPaint.setColor(res.getColor(R.color.color_1A693C26));
        drawLine(canvas);
    }

    private HashMap<String, int[]> mXAndMonth = new HashMap<>();// 月份和他对应的X坐标点

    /**
     * 画所有横向表格，包括X轴
     */
    private void drawAllXLine(Canvas canvas) {
        for (int i = 0; i < spacingHeight + 1; i++) {
            if (i == spacingHeight) {
                break;
            }

            canvas.drawLine(0, bheight
                            - (bheight / spacingHeight) * i + marginTop,
                    (canvasWidth - blwidh) - startXWidth, bheight
                            - (bheight / spacingHeight) * i + marginTop,
                    mPaint);// Y坐标
        }
    }

    /**
     * 画所有纵向表格，包括Y轴
     */
    private void drawAllYLine(Canvas canvas) {
        Paint yPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        yPaint.setColor(res.getColor(R.color.color_66693C26));
        for (int i = 0; i < yRawData.size(); i++) {
            xList.add(blwidh + (canvasWidth - blwidh) / yRawData.size() * i);
            canvas.drawLine(blwidh + (canvasWidth - blwidh) / yRawData.size()
                    * i - startXWidth, bheight + marginTop, blwidh + (canvasWidth - blwidh)
                    / yRawData.size() * i - startXWidth, bheight + 2 * marginTop, yPaint);
            drawText(xRawDatas.get(i), blwidh + (canvasWidth - blwidh)
                    / yRawData.size() * i - startXWidth, bheight + marginTop + dip2px(24), canvas);// X坐标
        }
    }


    private void drawText(String text, int x, int y, Canvas canvas) {
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
        p.setTextSize(dip2px(10));
        p.setColor(res.getColor(R.color.color_9C9C9C));
        p.setTextAlign(Paint.Align.CENTER);
        //屏幕分辨率的判断
        if (screenAll <= 720 * 1280) {
            canvas.drawText(text, x, y + dip2px(5), p);
        } else {
            canvas.drawText(text, x, y - dip2px(2), p);
        }
    }

    private void drawLine(Canvas canvas) {
        Paint xiePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        xiePaint.setColor(res.getColor(R.color.color_1A693C26));
        Point startp = new Point();
        Point endp = new Point();
        for (int i = 0; i < mPoints.length - 1; i++) {
            startp = mPoints[i];
            endp = mPoints[i + 1];

            //渐变色
//            LinearGradient linearGradient = new LinearGradient(0, 0, getMeasuredWidth(),
//                    0, new int[]{getResources().getColor(R.color.color_FFFFFF),
//                    getResources().getColor(R.color.color_1A693C26)}, null, LinearGradient.TileMode.CLAMP);
//            xiePaint.setShader(linearGradient);
            canvas.drawLine(startp.x - startXWidth, startp.y, endp.x - startXWidth, endp.y, xiePaint);
        }
    }


    private void drawTextY(String text, int x, int y, Canvas canvas) {
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
        p.setTextSize(dip2px(10));
        p.setColor(res.getColor(R.color.color_9C9C9C));
        p.setTextAlign(Paint.Align.CENTER);
        canvas.drawText(text, x + 10, y + dip2px(5), p);
    }

    private Point[] getPoints() {
        Point[] points = new Point[yRawData.size()];
        for (int i = 0; i < yRawData.size(); i++) {
            int ph = bheight - (int) (bheight * (yRawData.get(i) / maxValue));
            points[i] = new Point(xList.get(i), ph + marginTop);
        }
        return points;
    }

    public void setData(ArrayList<Double> yRawData, ArrayList<String> xRawData,
                        int maxValue, int averageValue, View mOutView) {
        if (mXAndMonth != null) {
            mXAndMonth.clear();
        }
        this.yRawData = yRawData;
        this.xRawDatas = xRawData;
        this.maxValue = maxValue;
        this.averageValue = averageValue;
        this.mPoints = new Point[yRawData.size()];
        this.mOutView = mOutView;

        contentView = View.inflate(mContext, R.layout.pop_window, null);// 弹窗布局
        tv_popWindow = contentView.findViewById(R.id.tv_popWindow);
    }

    private View contentView;
    private TextView tv_popWindow;

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    private int dip2px(float dpValue) {
        return (int) (dpValue * dm.density + 0.5f);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();// 点击时获取的X坐标点
        int y = (int) event.getY();// 点击时获取的Y坐标点
        String whichCircle = whichCircle(x, y);// 进行点与点之间判断返回月份
        setPopupWindow(whichCircle, x, y);
        return super.onTouchEvent(event);
    }


    /**
     * 根据点击获取的月份显示弹窗
     *
     * @param whichCircle
     */
    private void setPopupWindow(String whichCircle, int x, int y) {
        // TODO Auto-generated method stub
        if (!TextUtils.isEmpty(whichCircle)) {
            if (popupWindow != null) {// 弹窗不为空时进行是否显示判断，避免重复显示。由于点击时获取的坐标点不止一个
                boolean isShowing = popupWindow.isShowing();
                if (!isShowing) {
                    showPopupWindow(this, whichCircle, x, y);// 如果弹窗没有显示，再显示
                } else {
                    return;
                }
            } else {
                showPopupWindow(this, whichCircle, x, y);// 第一次弹窗为空，直接显示
            }
        }
    }


    /**
     * 显示弹窗在指定控件下方的指定坐标点
     *
     * @param view  指定控件下方
     * @param month 月份
     * @param x     横坐标
     * @param y     纵坐标
     */
    private void showPopupWindow(View view, String month, int x, int y) {
        tv_popWindow.setText(month);
        popupWindow = new PopupWindow(contentView, LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, true);// 创建弹窗指定大小
        popupWindow.setTouchable(true);
        popupWindow.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.popwindow_background));// 设置弹窗的背景
        popupWindow.showAsDropDown(mOutView, x - 30, y);// 在指定位置显示弹窗
    }


    private View mOutView;
    private PopupWindow popupWindow;


    /**
     * 根据两点之间距离判断点击的是哪个月的数据
     *
     * @param x 点击的x坐标
     * @param y 点击的y坐标
     * @return
     */
    private String whichCircle(int x, int y) {
        // TODO Auto-generated method stub
        String strData = "";
        double sqrt;
        for (int i = 0; i < mXAndMonth.size(); i++) {
            Iterator<?> iter = mXAndMonth.entrySet().iterator();
            while (iter.hasNext()) {
                @SuppressWarnings("rawtypes")
                Map.Entry entry = (Map.Entry) iter.next();
                String key = (String) entry.getKey();// 存储的月份
                int[] val = (int[]) entry.getValue();// 存储的月份对应的坐标

                if (val.length == 2) {
                    sqrt = Math.sqrt(Math.abs((x - val[0]) * (x - val[0])) + Math.abs((y - val[1]) * (y - val[1])));
                    if (CIRCLE_SIZE + 40 > sqrt) {
                        strData = key;
                    }
                }
            }
        }
        return strData;
    }

    public int CIRCLE_SIZE = 7;//远点直径
}
